/* ************************************************************************** *
 * See the NOTICE file distributed with this work for additional information
 * regarding copyright ownership.
 * 
 * This file is licensed to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 * ************************************************************************** */
package org.statewalker.fsm;

/**
 * Instances of this type are used to notify about individual steps of the
 * process. These instances are used by {@link FsmProcess}. When the process
 * enters in a new state then the {@link #onActivate(Object, Object, Object)}
 * method is called. The {@link #onDeactivate(Object, Object, Object)} method is
 * called to de-activate the state. The
 * {@link #onTransition(Object, Object, Object, Object)} method is called when
 * the process already de-activated the previous state but not activated yet the
 * next one.
 * <p>
 * Note that the process ({@link FsmProcess}) itself does not make anything when
 * it enters in or leaves a state. State listeners should be used to implement
 * actions associated with individual states.
 * </p>
 * 
 * @author kotelnikov
 * @param <S> the state type
 * @param <E> the type of events initializing transitions between states
 */
public interface IFsmStateListener<S, E> {

    /**
     * This method is used to activate a new state.
     * 
     * @param parent the parent state; the parent state could be
     *        <code>null</code> when this method is used to activate the root
     *        state (when the <code>state</code> parameter is the root state).
     * @param state the state to activate
     * @param event the event which initialized the transition in this state
     */
    void onActivate(S parent, S state, E event);

    /**
     * This method is used to de-activate a new state.
     * 
     * @param parent the parent state; the parent state could be
     *        <code>null</code> when this method is used to de-activate the root
     *        state (when the <code>state</code> parameter is the root state).
     * @param state the state to activate
     * @param event the event which initialized the transition out of this state
     */
    void onDeactivate(S parent, S state, E event);

    /**
     * This method is used to notify about transitions between two sub-states of
     * the parent state.
     * 
     * @param parent the parent state; this parameter could not be
     *        <code>null</code>
     * @param prev the previous state of this transition; this state could be
     *        <code>null</code> when the process enters in the parent state
     * @param event the event activating the transition between the previous and
     *        the next states.
     * @param next the target state of the transition; it could be
     *        <code>null</code> when the process leaves the parent state (when
     *        the previous state was the last sub-state in the parent)
     */
    void onTransition(S parent, S prev, E event, S next);

}